/*
 * JGO2RDF creates a RDF representation of GAF2 files, which are automatically sourced from GO ftp site.
 * Copyright (C) 2012 Matthew M. Hindle & Artem Lysenko
 *
 * This program is free software: you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program.  If not, see <http://www.gnu.org/licenses/>.
 */

package uk.co.jgo2rdf.tools;

import org.apache.commons.io.IOUtils;
import org.apache.log4j.Logger;

import java.io.IOException;
import java.io.InputStream;
import java.net.HttpURLConnection;
import java.net.URL;
import java.net.URLConnection;

/**
 * @author hindlem
 */
public class URLIOUtils {

    private static final Logger log = Logger.getLogger(URLIOUtils.class);

    public static byte[] getByteArray(URL url, int tries) throws IOException, InterruptedException {
        return getByteArray(url, 1, tries);
    }

    private static byte[] getByteArray(URL url, int i, int tries) throws IOException, InterruptedException {
        try {
            URLConnection conn = url.openConnection();
            HttpURLConnection.setFollowRedirects(true);
            conn.setConnectTimeout(60 * 1000);
            conn.setReadTimeout(60 * 1000);
            InputStream is = conn.getInputStream();
            try {
                byte[] bytes = IOUtils.toByteArray(is);
                return bytes;
            } finally {
                is.close();
            }

        } catch (IOException e) {
            if (i < tries) {
                log.warn("Could not connect to " + url + " attempting " + (tries - 1) + " more tries in " + i * 1000 + " second/s");
                Thread.sleep(i * 1000);
                return getByteArray(url, i + 1, tries);
            } else {
                log.error(e);
                throw e;
            }
        }
    }

    /**
     * A really useful tool for guessing the encoding of a byte[]
     *
     * @param bytes
     * @return the encoding
     */
    public static String guessEncoding(byte[] bytes) {
        String DEFAULT_ENCODING = "UTF-8";
        org.mozilla.universalchardet.UniversalDetector detector =
                new org.mozilla.universalchardet.UniversalDetector(null);
        detector.handleData(bytes, 0, bytes.length);
        detector.dataEnd();
        String encoding = detector.getDetectedCharset();
        detector.reset();
        if (encoding.equalsIgnoreCase(null)) ;
        {
            encoding = DEFAULT_ENCODING;
        }
        return encoding;
    }

    /**
     * A way on inter-converting to VTD compatible
     *
     * @param encoding
     * @return
     */
    public static int convertToVTDCode(String encoding) {
        encoding = encoding.trim().replaceAll("-| ", "_");
        encoding = encoding.replaceAll("WINDOWS", "WIN");
        if (encoding.equalsIgnoreCase("ASCII")) return 0;
        else if (encoding.equalsIgnoreCase("ISO_8859_1")) return 1;
        else if (encoding.equalsIgnoreCase("ISO_8859_10")) return 11;
        else if (encoding.equalsIgnoreCase("ISO_8859_11")) return 12;
        else if (encoding.equalsIgnoreCase("ISO_8859_12")) return 13;
        else if (encoding.equalsIgnoreCase("ISO_8859_13")) return 14;
        else if (encoding.equalsIgnoreCase("ISO_8859_14")) return 15;
        else if (encoding.equalsIgnoreCase("ISO_8859_15")) return 16;
        else if (encoding.equalsIgnoreCase("ISO_8859_16")) return 17;
        else if (encoding.equalsIgnoreCase("ISO_8859_2")) return 3;
        else if (encoding.equalsIgnoreCase("ISO_8859_3")) return 4;
        else if (encoding.equalsIgnoreCase("ISO_8859_4")) return 5;
        else if (encoding.equalsIgnoreCase("ISO_8859_5")) return 6;
        else if (encoding.equalsIgnoreCase("ISO_8859_6")) return 7;
        else if (encoding.equalsIgnoreCase("ISO_8859_7")) return 8;
        else if (encoding.equalsIgnoreCase("ISO_8859_8")) return 9;
        else if (encoding.equalsIgnoreCase("ISO_8859_9")) return 10;
        else if (encoding.equalsIgnoreCase("UTF_16BE")) return 63;
        else if (encoding.equalsIgnoreCase("UTF_16LE")) return 64;
        else if (encoding.equalsIgnoreCase("UTF8")) return 2;
        else if (encoding.equalsIgnoreCase("UTF_8")) return 2;
        else if (encoding.equalsIgnoreCase("WIN_1250")) return 18;
        else if (encoding.equalsIgnoreCase("WIN_1251")) return 19;
        else if (encoding.equalsIgnoreCase("WIN_1252")) return 20;
        else if (encoding.equalsIgnoreCase("WIN_1253")) return 21;
        else if (encoding.equalsIgnoreCase("WIN_1254")) return 22;
        else if (encoding.equalsIgnoreCase("WIN_1255")) return 23;
        else if (encoding.equalsIgnoreCase("WIN_1256")) return 24;
        else if (encoding.equalsIgnoreCase("WIN_1257")) return 25;
        else if (encoding.equalsIgnoreCase("WIN_1258")) return 26;
        else return 2; //default UTF-8
    }


}
